package com.talkweb.baselibrary.utils;

import ohos.app.AbilityContext;
import ohos.app.Context;
import ohos.data.usage.DataUsage;
import ohos.data.usage.MountState;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Rect;
import ohos.media.image.common.Size;

import java.io.*;

public final class FileUtils {


    private static final int BUFFER = 8192;
    private static final String Tag = "FileUtils";

    private FileUtils() {
    }


    /**
     * 读取文件
     *
     * @param file
     * @return
     * @throws IOException
     */
    public static String readTextFile(File file) throws IOException {
        String text = null;
        InputStream is = null;
        try {
            is = new FileInputStream(file);
            text = readTextInputStream(is);
        } finally {
            if (is != null) {
                is.close();
            }
        }
        return text;
    }

    /**
     * 从流中读取文件
     *
     * @param is
     * @return
     * @throws IOException
     */
    public static String readTextInputStream(InputStream is) throws IOException {
        StringBuffer strbuffer = new StringBuffer();
        String line;
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(is));
            while ((line = reader.readLine()) != null) {
                strbuffer.append(line).append("\r\n");
            }
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
        return strbuffer.toString();
    }

    /**
     * 将文本内容写入文件
     *
     * @param file
     * @param str
     * @throws IOException
     */
    public static void writeTextFile(File file, String str) throws IOException {
        DataOutputStream out = null;
        try {
            out = new DataOutputStream(new FileOutputStream(file));
            out.write(str.getBytes());
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }

    /**
     * 把流写入文件
     *
     * @param path
     * @param input
     * @throws IOException
     */
    public static void writeToLocal(String path, InputStream input)
            throws IOException {
        int index;
        byte[] bytes = new byte[BUFFER];
        FileOutputStream downloadFile = null;
        try {
            downloadFile = new FileOutputStream(path);
            while ((index = input.read(bytes)) != -1) {
                downloadFile.write(bytes, 0, index);
            }
            downloadFile.flush();
        } finally {
            if (downloadFile != null) {
                downloadFile.close();
            }
            if (input != null) {
                input.close();
            }
        }
    }


    /**
     * 复制文件
     *
     * @param sourceFile
     * @param targetFile
     * @throws IOException
     */
    public static void copyFile(File sourceFile, File targetFile)
            throws IOException {
        BufferedInputStream inBuff = null;
        BufferedOutputStream outBuff = null;
        try {
            //////////////////
            //////////////没有这句代码  当父文件夹不存在时，
            //复制很可能会失败
            File file = targetFile.getParentFile();
            if (file == null) {
                return;
            }
            if (!file.exists()) {
                file.mkdirs();
            }
            //////////////

            inBuff = new BufferedInputStream(new FileInputStream(sourceFile));
            outBuff = new BufferedOutputStream(new FileOutputStream(targetFile));
            byte[] buffer = new byte[BUFFER];
            int length;
            while ((length = inBuff.read(buffer)) != -1) {
                outBuff.write(buffer, 0, length);
            }
            outBuff.flush();
        } finally {
            if (inBuff != null) {
                inBuff.close();
            }
            if (outBuff != null) {
                outBuff.close();
            }
        }
    }

    /**
     * 创建文件夹
     *
     * @param dir
     */

    public static boolean createDir(String dir) {
        File folderDir = new File(dir);
        if (!folderDir.exists()) {
            return folderDir.mkdirs();
        } else {
            LogUtil.i(Tag, "文件夹存在：" + dir);
        }
        return true;
    }

    /**
     * 创建文件夹 (hap目录下)
     *
     * @param context
     * @param dir
     */

    public static boolean createDir(Context context, String dir) {
        File folderDir = new File(getFilePath(context, dir));
        if (!folderDir.exists()) {
            return folderDir.mkdirs();
        } else {
            LogUtil.i(Tag, "文件夹存在：" + folderDir);
        }
        return true;
    }

    /**
     * 创建文件
     *
     * @param dir
     * @param fileName
     * @return
     */
    public static File createFile(String dir, String fileName) {
        File folderDir = new File(dir);
        if (!folderDir.exists()) {
            folderDir.mkdirs();
        }
        String filePath;
        if (dir.endsWith(File.separator)) {
            filePath = dir + fileName;
        } else {
            filePath = dir + File.separator + fileName;
        }
        File fileNew = new File(filePath);
        if (!fileNew.exists()) {
            try {
                fileNew.createNewFile();
            } catch (IOException e) {
                return null;
            }
        }
        return fileNew;
    }

    /**
     * 创建文件
     *
     * @param ct
     * @param dir
     * @param fileName
     * @return
     */
    public static File createFile(Context ct, String dir, String fileName) {
        createDirIfNotExist(getFilePath(ct, dir));

        String filePath = getFilePath(ct, dir) + fileName;
        File fileNew = new File(filePath);
        if (!fileNew.exists()) {
            try {
                fileNew.createNewFile();
            } catch (IOException e) {
                LogUtil.e(Tag, "异常文件路径：" + filePath + ",error:" + e.getMessage());
                return null;
            }
        }
        return fileNew;
    }

    /**
     * 创建文件用于缓存
     *
     * @param context
     * @param cacheDir
     * @param subDir
     * @param fileName
     * @return
     */
    public static File createFile(Context context, String cacheDir,
                                  String subDir, String fileName) {
        if (!isDirExist(context, cacheDir)) {
            File file = new File(getFilePath(context, cacheDir));
            file.mkdirs();
        }

        String cacheTempDir = getFilePath(context, cacheDir, subDir);
        File fileDir = new File(cacheTempDir);
        if (!fileDir.exists()) {
            File subFile = new File(cacheTempDir);
            subFile.mkdirs();
        }

        String fileTargetDir = cacheTempDir + fileName;
        File fileNew = new File(fileTargetDir);
        if (!fileNew.exists()) {
            try {
                fileNew.createNewFile();
            } catch (IOException e) {
                return null;
            }
        }

        return fileNew;
    }

    /**
     * 获取文件的路径
     *
     * @param context
     * @param cacheDir
     * @return
     */
    public static String getFilePath(Context context, String cacheDir) {
        String path;
        if (!StringUtils.isEmpty(cacheDir)) {
            path = getFilePath(context, cacheDir, "");
        } else {
            path = getAppFilesDir(context);
        }
        return path;
    }

    /**
     * 获取文件夹路径
     *
     * @param context
     * @param cacheDir
     * @param subDir
     * @return
     */
    public static String getFilePath(Context context, String cacheDir,
                                     String subDir) {
        String baseDir = getAppFilesDir(context);
        if (!StringUtils.isEmpty(cacheDir)) {
            baseDir = baseDir + cacheDir + File.separator;
            if (!StringUtils.isEmpty(subDir)) {
                baseDir = baseDir + subDir + File.separator;
            }
        }
        if (!StringUtils.isEmpty(subDir)) {
            baseDir = baseDir + subDir + File.separator;
        }
        createDirIfNotExist(baseDir);
        return baseDir;
    }

    /**
     * 递归删除文件夹（包含根目录）
     *
     * @param path
     */
    public static void deleteDir(String path) {
        deleteDir(path, true);
    }

    /**
     * 递归删除文件
     *
     * @param path         文件夹路径
     * @param isDeleteSelf 是否删除根目录
     */
    public static void deleteDir(String path, boolean isDeleteSelf) {
        File dir = new File(path);
        if (!dir.exists() || !dir.isDirectory()) return;

        for (File file : dir.listFiles()) {
            if (file.isFile()) file.delete(); // 删除所有文件
            else if (file.isDirectory()) deleteDir(file.getPath(), true); // 递规的方式删除文件夹
        }
        if (isDeleteSelf) {
            dir.delete();// 删除目录本身
        }
    }

    /**
     * 文件目录是否存在（hap应用目录下）
     *
     * @param context
     * @param cacheDir
     * @return
     */
    public static boolean isDirExist(Context context, String cacheDir) {
        return !StringUtils.isEmpty(cacheDir) && isDirExist(getFilePath(context, cacheDir));
    }

    /**
     * 文件目录是否存在
     *
     * @param cacheDir 完整路径
     * @return
     */
    public static boolean isDirExist(String cacheDir) {
        if (StringUtils.isEmpty(cacheDir)) return false;
        File file = new File(cacheDir);
        return file.isDirectory();
    }

    /**
     * 文件是否存在（hap应用目录下）
     *
     * @param ct
     * @param fileName 文件名
     * @return
     */
    public static boolean isFileExist(Context ct, String fileName) {
        if (StringUtils.isEmpty(fileName)) return false;
        return isExist(new File(getAppFilesDir(ct), fileName));
    }

    public static boolean isFileExist(Context ct, String dir, String fileName) {
        if (StringUtils.isEmpty(fileName) || StringUtils.isEmpty(dir)) return false;
        return isExist(new File(getFilePath(ct, dir), fileName));
    }

    /**
     * 文件是否存在
     *
     * @param filePath 文件完整路径
     * @return
     */
    public static boolean isFileExist(String filePath) {
        if (StringUtils.isEmpty(filePath)) return false;
        return isExist(new File(filePath));
    }

    /**
     * 文件是否存在
     *
     * @param dir      文件完整路径
     * @param fileName 文件名
     * @return
     */
    public static boolean isFileExist(String dir, String fileName) {
        if (StringUtils.isEmpty(fileName) || StringUtils.isEmpty(dir)) return false;
        String filePath = dir;
        if (dir.endsWith(File.separator)) {
            filePath = dir + fileName;
        } else {
            filePath = dir + File.separator + fileName;
        }
        return isExist(new File(filePath));
    }

    /**
     * 根据传入的文件路径判断此文件是否存在
     *
     * @param file
     * @return
     */
    public static boolean isExist(File file) {
        return file != null && file.exists();
    }

    /**
     * 根据传入的文件路径创建文件夹，若不存在则新建
     *
     * @param dirPath
     * @return
     */
    public static File createDirIfNotExist(String dirPath) {
        File file = new File(dirPath);
        if (!file.exists()) {
            file.mkdirs();
        } else {
            LogUtil.i(Tag, "文件夹存在：" + dirPath);
        }
        File[] al = file.listFiles();
        if (al != null)
            for (File file1 : al) {
                LogUtil.i(Tag, "list文件：" + file1.getAbsolutePath());
            }
        else {
            LogUtil.i(Tag, "无法list文件夹：" + dirPath);
        }
        return file;
    }


    public static String getFileName(String filePath) {
        if (StringUtils.isEmpty(filePath)) {
            return System.currentTimeMillis() + "";
        }
        return filePath.substring(filePath.lastIndexOf(File.separator) + 1);

    }

    public static boolean hasSDCard() {
        MountState state = DataUsage.getDiskMountedStatus();
        return state.equals(MountState.DISK_MOUNTED);
    }


    // "/data/data/包名/files/"
    public static String getAppFilesDir(Context context) {
        return context.getFilesDir().getAbsolutePath() + File.separator;
    }

    // "/data/data/包名/cache/"
    public static String getAppCacheDir(Context context) {
        return context.getCacheDir().getAbsolutePath() + File.separator;
    }

    public static boolean deleteFile(String filePath) {
        File file = new File(filePath);
        return deleteFile(file);
    }

    public static boolean deleteFile(Context ct, String strFileName) {
        File file = new File(getAppFilesDir(ct), strFileName);
        return deleteFile(file);
    }

    public static boolean deleteFile(File file) {
        if (!file.exists()) {
        } else {
            if (file.isFile()) {
                return file.delete();
            }
            if (file.isDirectory()) {
                File[] childFile = file.listFiles();
                if (childFile == null || childFile.length == 0) {
                    return file.delete();
                }
                for (File f : childFile) {
                    deleteFile(f);
                }
                return file.delete();
            }
        }
        return false;
    }

    /**
     * 待完善 2020.12.30
     *
     * @param context
     * @param fileName
     * @return
     */
    @Deprecated
    public static String readRawFile(Context context, String fileName) {
        try {
            FileDescriptor fd = context.getResourceManager().getRawFileEntry(fileName).openRawFileDescriptor().getFileDescriptor();

            InputStream is = new FileInputStream(fd);
            InputStreamReader reader = new InputStreamReader(is);
            BufferedReader bufReader = new BufferedReader(reader);

            String strLine = "";
            StringBuilder result = new StringBuilder();
            while ((strLine = bufReader.readLine()) != null)
                result.append(strLine);
            return result.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    ///创建相册文件夹
    public static File createGalleryFold(AbilityContext context, String foldName) {

        File baseDir = context.getCacheDir();
        File galleryDir = new File(baseDir, foldName);
        if (!galleryDir.exists()) {
            try {
                galleryDir.mkdirs();
            } catch (Exception e) {

            }

        }
        return galleryDir;
    }

    /**
     * 通过资源ID获取位图对象
     **/
    public static PixelMap getPixelMap(Context context, int drawableId) {
        InputStream drawableInputStream = null;
        try {
            drawableInputStream = context.getResourceManager().getResource(drawableId);
            ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions();
            sourceOptions.formatHint = "image/png";
            ImageSource imageSource = ImageSource.create(drawableInputStream, sourceOptions);
            ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
            decodingOptions.desiredSize = new Size(0, 0);
            decodingOptions.desiredRegion = new Rect(0, 0, 0, 0);
            decodingOptions.desiredPixelFormat = PixelFormat.ARGB_8888;
            PixelMap pixelMap = imageSource.createPixelmap(decodingOptions);
            return pixelMap;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try{
                if (drawableInputStream != null){
                    drawableInputStream.close();
                }
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

}
